package com.example.suhui_test.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 可拖拽圆形View
 * 知识点：
 * 1. 触摸事件处理 - onTouchEvent方法
 * 2. 事件类型判断 - ACTION_DOWN, ACTION_MOVE, ACTION_UP
 * 3. 坐标计算和边界检测
 * 4. 自定义回调接口
 * 5. 动态绘制和实时更新
 * 6. 触摸反馈效果
 */
public class DraggableCircleView extends View {
    
    // 圆形属性
    private static final float CIRCLE_RADIUS = 60f;
    private static final int CIRCLE_COLOR = 0xFF4CAF50;
    private static final int CIRCLE_COLOR_PRESSED = 0xFF2E7D32;
    private static final int TRAIL_COLOR = 0x804CAF50;
    
    // 圆形位置
    private float circleX;
    private float circleY;
    private float radius = CIRCLE_RADIUS;
    
    // 触摸状态
    private boolean isDragging = false;
    private float lastTouchX;
    private float lastTouchY;
    
    // 最小移动距离，避免微小抖动
    private static final float MIN_MOVE_DISTANCE = 5f;
    
    // 绘制相关
    private Paint circlePaint;
    private Paint trailPaint;
    private Path trailPath;
    
    // 回调接口
    private OnPositionChangeListener onPositionChangeListener;
    
    /**
     * 位置变化监听接口
     */
    public interface OnPositionChangeListener {
        void onPositionChanged(float x, float y);
    }

    public DraggableCircleView(Context context) {
        this(context, null);
    }

    public DraggableCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DraggableCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
        initPosition();
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        // 圆形画笔
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(CIRCLE_COLOR);
        circlePaint.setStyle(Paint.Style.FILL);
        
        // 轨迹画笔
        trailPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        trailPaint.setColor(TRAIL_COLOR);
        trailPaint.setStyle(Paint.Style.STROKE);
        trailPaint.setStrokeWidth(8f);
        trailPaint.setStrokeCap(Paint.Cap.ROUND);
        
        // 轨迹路径
        trailPath = new Path();
    }

    /**
     * 初始化位置
     */
    private void initPosition() {
        // 初始位置设在中心
        circleX = 200f;
        circleY = 200f;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        
        // 当View尺寸确定后，设置初始位置为中心
        circleX = w / 2f;
        circleY = h / 2f;
        
        // 重置轨迹路径
        trailPath.reset();
        trailPath.moveTo(circleX, circleY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        // 绘制拖拽轨迹
        canvas.drawPath(trailPath, trailPaint);
        
        // 绘制圆形
        canvas.drawCircle(circleX, circleY, radius, circlePaint);
        
        // 绘制中心点
        Paint centerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        centerPaint.setColor(0xFFFFFFFF);
        canvas.drawCircle(circleX, circleY, 8f, centerPaint);
        
        // 如果正在拖拽，绘制额外的视觉效果
        if (isDragging) {
            Paint shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            shadowPaint.setColor(0x40000000);
            canvas.drawCircle(circleX + 5, circleY + 5, radius, shadowPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();
        
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 检查触摸点是否在圆形内
                if (isPointInCircle(touchX, touchY)) {
                    isDragging = true;
                    lastTouchX = touchX;
                    lastTouchY = touchY;
                    
                    // 改变圆形颜色表示按下状态
                    circlePaint.setColor(CIRCLE_COLOR_PRESSED);
                    
                    // 清除之前的轨迹，开始新的轨迹
                    trailPath.reset();
                    trailPath.moveTo(circleX, circleY);
                    
                    // 请求父容器不要拦截触摸事件
                    getParent().requestDisallowInterceptTouchEvent(true);
                    
                    invalidate();
                    return true;
                }
                break;
                
            case MotionEvent.ACTION_MOVE:
                if (isDragging) {
                    // 计算移动距离
                    float deltaX = touchX - lastTouchX;
                    float deltaY = touchY - lastTouchY;
                    
                    // 检查移动距离是否足够大，避免微小抖动
                    float moveDistance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
                    if (moveDistance > MIN_MOVE_DISTANCE) {
                        // 更新圆形位置
                        circleX += deltaX;
                        circleY += deltaY;
                        
                        // 边界检测
                        checkBounds();
                        
                        // 添加到轨迹路径
                        trailPath.lineTo(circleX, circleY);
                        
                        // 更新触摸位置
                        lastTouchX = touchX;
                        lastTouchY = touchY;
                        
                        // 触发位置变化回调
                        if (onPositionChangeListener != null) {
                            onPositionChangeListener.onPositionChanged(circleX, circleY);
                        }
                        
                        invalidate();
                    }
                    return true;
                }
                break;
                
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (isDragging) {
                    isDragging = false;
                    
                    // 恢复圆形颜色
                    circlePaint.setColor(CIRCLE_COLOR);
                    
                    // 恢复父容器的触摸事件拦截
                    getParent().requestDisallowInterceptTouchEvent(false);
                    
                    invalidate();
                    return true;
                }
                break;
        }
        
        return super.onTouchEvent(event);
    }

    /**
     * 检查点是否在圆形内
     */
    private boolean isPointInCircle(float x, float y) {
        float distance = (float) Math.sqrt(Math.pow(x - circleX, 2) + Math.pow(y - circleY, 2));
        return distance <= radius;
    }

    /**
     * 边界检测，确保圆形不会超出View边界
     */
    private void checkBounds() {
        int width = getWidth();
        int height = getHeight();
        
        if (circleX - radius < 0) {
            circleX = radius;
        } else if (circleX + radius > width) {
            circleX = width - radius;
        }
        
        if (circleY - radius < 0) {
            circleY = radius;
        } else if (circleY + radius > height) {
            circleY = height - radius;
        }
    }

    /**
     * 设置位置变化监听器
     */
    public void setOnPositionChangeListener(OnPositionChangeListener listener) {
        this.onPositionChangeListener = listener;
    }

    /**
     * 获取圆形X坐标
     */
    public float getCircleX() {
        return circleX;
    }

    /**
     * 获取圆形Y坐标
     */
    public float getCircleY() {
        return circleY;
    }

    /**
     * 设置圆形位置
     */
    public void setCirclePosition(float x, float y) {
        this.circleX = x;
        this.circleY = y;
        checkBounds();
        invalidate();
    }

    /**
     * 重置圆形到中心位置
     */
    public void resetToCenter() {
        circleX = getWidth() / 2f;
        circleY = getHeight() / 2f;
        trailPath.reset();
        trailPath.moveTo(circleX, circleY);
        invalidate();
    }

    /**
     * 清除轨迹
     */
    public void clearTrail() {
        trailPath.reset();
        trailPath.moveTo(circleX, circleY);
        invalidate();
    }
}